﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="PrimitiveTypes.cs" company="DissingNellemann">
//   
// All rights reserved </copyright>
// <summary>
//   The primitive types.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Website.Models
{
    using System;
using System.Collections.Generic;
using System.Linq;
using Website.CRUDServices;
using Website.Models.ViewModels;
using Location = Website.Models.Domain.Location;
using Region = Website.Models.Domain.Region;

    /// <summary>
    ///     The primitive types.
    /// </summary>
    public static class PrimitiveTypes
    {
        #region Public Methods and Operators

        /// <summary>
        ///     The get cluster method type.
        /// </summary>
        /// <returns>
        ///     The <see cref="List" />.
        /// </returns>
        public static List<ClusterMethodType> GetClusterMethodType()
        {
            var clusterMethodTypes = new List<ClusterMethodType>();

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var cq = new ClusterMethodTypeQuery();
                    cq.Settings = new SearchSettings();
                    var cqResult = (ClusterMethodTypeResult)client.Query(cq);
                    if (cqResult != null)
                    {
                        foreach (ClusterMethodType dto in cqResult.List)
                        {
                            if (dto != null)
                            {
                                clusterMethodTypes.Add(dto);
                            }
                        }
                    }
                });

            return clusterMethodTypes;
        }

        /// <summary>
        /// The get cluster methods with i ds.
        /// </summary>
        /// <param name="IDs">
        /// The i ds.
        /// </param>
        /// <returns>
        /// The <see cref="List"/>.
        /// </returns>
        public static List<CRUDServices.ClusterMethod> GetClusterMethodsWithIDs(IEnumerable<Guid> IDs)
        {
            var clusterMethods = new List<CRUDServices.ClusterMethod>();

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var cq = new ClusterMethodQuery();
                    cq.Settings = new SearchSettings();
                    if (IDs != null && IDs.Count() > 0)
                    {
                        cq.Settings.IDIsIn = IDs.ToArray();
                    }

                    var cqResult = (ClusterMethodResult)client.Query(cq);
                    if (cqResult != null)
                    {
                        foreach (CRUDServices.ClusterMethod dto in cqResult.List)
                        {
                            if (dto != null)
                            {
                                clusterMethods.Add(dto);
                            }
                        }
                    }
                });

            return clusterMethods;
        }

        /// <summary>
        ///     The get cluster status type.
        /// </summary>
        /// <returns>
        ///     The <see cref="List" />.
        /// </returns>
        public static List<ClusterStatusType> GetClusterStatusType()
        {
            var clusterStatusTypes = new List<ClusterStatusType>();

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var cq = new ClusterStatusTypeQuery();
                    cq.Settings = new SearchSettings();
                    var cqResult = (ClusterStatusTypeResult)client.Query(cq);
                    if (cqResult != null)
                    {
                        foreach (ClusterStatusType dto in cqResult.List)
                        {
                            if (dto != null)
                            {
                                clusterStatusTypes.Add(dto);
                            }
                        }
                    }
                });

            return clusterStatusTypes;
        }

        /// <summary>
        /// The get cluster status with i ds.
        /// </summary>
        /// <param name="IDs">
        /// The i ds.
        /// </param>
        /// <returns>
        /// The <see cref="List"/>.
        /// </returns>
        public static List<CRUDServices.ClusterStatus> GetClusterStatusWithIDs(IEnumerable<Guid> IDs)
        {
            var clusterStatus = new List<CRUDServices.ClusterStatus>();

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var cq = new ClusterStatusQuery();
                    cq.Settings = new SearchSettings();
                    if (IDs != null && IDs.Count() > 0)
                    {
                        cq.Settings.IDIsIn = IDs.ToArray();
                    }

                    var cqResult = (ClusterStatusResult)client.Query(cq);
                    if (cqResult != null)
                    {
                        foreach (CRUDServices.ClusterStatus dto in cqResult.List)
                        {
                            if (dto != null)
                            {
                                clusterStatus.Add(dto);
                            }
                        }
                    }
                });

            return clusterStatus;
        }

        /// <summary>
        ///     The get demonstrations.
        /// </summary>
        /// <returns>
        ///     The <see cref="List" />.
        /// </returns>
        public static List<ProjectMeetingDemonstration> GetDemonstrations()
        {
            var demos = new List<ProjectMeetingDemonstration>();

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var rq = new ProjectMeetingDemonstrationQuery();
                    rq.Settings = new SearchSettings();
                    var rqResult = (ProjectMeetingDemonstrationResult)client.Query(rq);
                    if (rqResult != null)
                    {
                        foreach (ProjectMeetingDemonstration dto in rqResult.List)
                        {
                            if (dto != null)
                            {
                                demos.Add(dto);
                            }
                        }
                    }
                });

            return demos;
        }

        /// <summary>
        ///     The get funds.
        /// </summary>
        /// <returns>
        ///     The <see cref="List" />.
        /// </returns>
        public static List<Fund> GetFunds()
        {
            var funds = new List<Fund>();

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var rq = new FundQuery();
                    rq.Settings = new SearchSettings();
                    var rqResult = (FundResult)client.Query(rq);
                    if (rqResult != null)
                    {
                        foreach (Fund dto in rqResult.List)
                        {
                            if (dto != null)
                            {
                                funds.Add(dto);
                            }
                        }
                    }
                });

            return funds;
        }

        /// <summary>
        ///     The get groups.
        /// </summary>
        /// <returns>
        ///     The <see cref="List" />.
        /// </returns>
        public static List<Group> GetGroups()
        {
            var profiles = new List<Group>();

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var rq = new GroupQuery();
                    rq.Settings = new SearchSettings();
                    var rqResult = (GroupResult)client.Query(rq);
                    if (rqResult != null)
                    {
                        foreach (Group dto in rqResult.List)
                        {
                            if (dto != null)
                            {
                                profiles.Add(dto);
                            }
                        }
                    }
                });

            return profiles;
        }

        /// <summary>
        ///     The get locations.
        /// </summary>
        /// <returns>
        ///     The <see cref="List" />.
        /// </returns>
        public static List<Location> GetLocations()
        {
            var locations = new List<Location>();

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var rq = new LocationsQuery();
                    rq.Settings = new SearchSettings();
                    var rqResult = (LocationsResult)client.Query(rq);
                    if (rqResult != null)
                    {
                        foreach (CRUDServices.Location dto in rqResult.List)
                        {
                            if (dto != null)
                            {
                                locations.Add(Location.Convert(dto));
                            }
                        }
                    }
                });

            return locations;
        }

        /// <summary>
        /// The get matchmaking partner types.
        /// </summary>
        /// <param name="IDs">
        /// The i ds.
        /// </param>
        /// <returns>
        /// The <see cref="List"/>.
        /// </returns>
        public static List<MatchmakingPartnerType> GetMatchmakingPartnerTypes(IEnumerable<Guid> IDs)
        {
            var profiles = new List<MatchmakingPartnerType>();

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var rq = new MatchmakingPartnerTypeQuery();
                    rq.Settings = new SearchSettings();
                    if (IDs != null && IDs.Count() > 0)
                    {
                        rq.Settings.IDIsIn = IDs.ToArray();
                    }

                    var rqResult = (MatchmakingPartnerTypeResult)client.Query(rq);
                    if (rqResult != null)
                    {
                        foreach (MatchmakingPartnerType dto in rqResult.List)
                        {
                            if (dto != null)
                            {
                                profiles.Add(dto);
                            }
                        }
                    }
                });

            return profiles;
        }

        /// <summary>
        ///     The get matchmaking partner types.
        /// </summary>
        /// <returns>
        ///     The <see cref="List" />.
        /// </returns>
        public static List<MatchmakingPartnerType> GetMatchmakingPartnerTypes()
        {
            var types = new List<MatchmakingPartnerType>();

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var rq = new MatchmakingPartnerTypeQuery();
                    rq.Settings = new SearchSettings();
                    var rqResult = (MatchmakingPartnerTypeResult)client.Query(rq);
                    if (rqResult != null)
                    {
                        foreach (MatchmakingPartnerType dto in rqResult.List)
                        {
                            if (dto != null)
                            {
                                types.Add(dto);
                            }
                        }
                    }
                });

            return types;
        }

        /// <summary>
        ///     The get matchmaking partners.
        /// </summary>
        /// <returns>
        ///     The <see cref="List" />.
        /// </returns>
        public static List<MatchmakingPartner> GetMatchmakingPartners()
        {
            var partners = new List<MatchmakingPartner>();

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var rq = new MatchmakingPartnerQuery();
                    rq.Settings = new SearchSettings();
                    var rqResult = (MatchmakingPartnerResult)client.Query(rq);
                    if (rqResult != null)
                    {
                        foreach (MatchmakingPartner dto in rqResult.List)
                        {
                            if (dto != null)
                            {
                                partners.Add(dto);
                            }
                        }
                    }
                });

            return partners;
        }

        /// <summary>
        ///     The get news information types.
        /// </summary>
        /// <returns>
        ///     The <see cref="List" />.
        /// </returns>
        public static List<NewsInformationType> GetNewsInformationTypes()
        {
            var types = new List<NewsInformationType>();

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var rq = new NewsInformationTypeQuery();
                    rq.Settings = new SearchSettings();
                    var rqResult = (NewsInformationTypeResult)client.Query(rq);
                    if (rqResult != null)
                    {
                        foreach (NewsInformationType dto in rqResult.List)
                        {
                            if (dto != null)
                            {
                                types.Add(dto);
                            }
                        }
                    }
                });

            return types;
        }

        /// <summary>
        /// The get news information types with i ds.
        /// </summary>
        /// <param name="IDs">
        /// The i ds.
        /// </param>
        /// <returns>
        /// The <see cref="List"/>.
        /// </returns>
        public static List<NewsInformationType> GetNewsInformationTypesWithIDs(IEnumerable<Guid> IDs)
        {
            var types = new List<NewsInformationType>();

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var rq = new NewsInformationTypeQuery();
                    rq.Settings = new SearchSettings();
                    if (IDs != null && IDs.Count() > 0)
                    {
                        rq.Settings.IDIsIn = IDs.ToArray();
                    }

                    var rqResult = (NewsInformationTypeResult)client.Query(rq);
                    if (rqResult != null)
                    {
                        foreach (NewsInformationType dto in rqResult.List)
                        {
                            if (dto != null)
                            {
                                types.Add(dto);
                            }
                        }
                    }
                });

            return types;
        }

        /// <summary>
        ///     The get presentations.
        /// </summary>
        /// <returns>
        ///     The <see cref="List" />.
        /// </returns>
        public static List<Presentation> GetPresentations()
        {
            return GetPresentationsWithIDs(new List<Guid>());
        }

        // get a list of all presentations
        /// <summary>
        /// The get presentations with i ds.
        /// </summary>
        /// <param name="IDs">
        /// The i ds.
        /// </param>
        /// <returns>
        /// The <see cref="List"/>.
        /// </returns>
        public static List<Presentation> GetPresentationsWithIDs(IEnumerable<Guid> IDs)
        {
            var presentations = new List<Presentation>();

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var cq = new PresentationQuery();
                    cq.Settings = new SearchSettings();
                    if (IDs != null && IDs.Count() > 0)
                    {
                        cq.Settings.IDIsIn = IDs.ToArray();
                    }

                    var cqResult = (PresentationResult)client.Query(cq);
                    if (cqResult != null)
                    {
                        foreach (Presentation dto in cqResult.List)
                        {
                            if (dto != null)
                            {
                                presentations.Add(dto);
                            }
                        }
                    }
                });

            return presentations;
        }

        /// <summary>
        ///     The get profiles.
        /// </summary>
        /// <returns>
        ///     The <see cref="List" />.
        /// </returns>
        public static List<Profile> GetProfiles()
        {
            return GetProfilesWithIDs(new List<Guid>());
        }

        // Get a list of all profiles
        /// <summary>
        /// The get profiles with i ds.
        /// </summary>
        /// <param name="IDs">
        /// The i ds.
        /// </param>
        /// <returns>
        /// The <see cref="List"/>.
        /// </returns>
        public static List<Profile> GetProfilesWithIDs(IEnumerable<Guid> IDs)
        {
            var profiles = new List<Profile>();

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var rq = new ProfilesQuery();
                    rq.Settings = new SearchSettings();
                    if (IDs != null && IDs.Count() > 0)
                    {
                        rq.Settings.IDIsIn = IDs.ToArray();
                    }

                    var rqResult = (ProfilesResult)client.Query(rq);
                    if (rqResult != null)
                    {
                        foreach (Profile dto in rqResult.List)
                        {
                            if (dto != null)
                            {
                                profiles.Add(dto);
                            }
                        }
                    }
                });

            return profiles;
        }

        // Get a list of all newsinfiormationtypes with ID's

        // Get a list of all profiles
        /// <summary>
        /// The get project type with i ds.
        /// </summary>
        /// <param name="IDs">
        /// The i ds.
        /// </param>
        /// <returns>
        /// The <see cref="List"/>.
        /// </returns>
        public static List<ProjectType> GetProjectTypeWithIDs(IEnumerable<Guid> IDs)
        {
            var projectTypes = new List<ProjectType>();

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var rq = new ProjectTypeQuery();
                    rq.Settings = new SearchSettings();
                    if (IDs != null && IDs.Count() > 0)
                    {
                        rq.Settings.IDIsIn = IDs.ToArray();
                    }

                    var rqResult = (ProjectTypeResult)client.Query(rq);
                    if (rqResult != null)
                    {
                        foreach (ProjectType dto in rqResult.List)
                        {
                            if (dto != null)
                            {
                                projectTypes.Add(dto);
                            }
                        }
                    }
                });

            return projectTypes;
        }

        /// <summary>
        ///     The get project types.
        /// </summary>
        /// <returns>
        ///     The <see cref="List" />.
        /// </returns>
        public static List<ProjectType> GetProjectTypes()
        {
            return GetProjectTypeWithIDs(new List<Guid>());
        }

        // Get a list of all roles

        // Get a list of all projects
        /// <summary>
        ///     The get projects.
        /// </summary>
        /// <returns>
        ///     The <see cref="List" />.
        /// </returns>
        public static List<CRUDServices.Project> GetProjects()
        {
            var projects = new List<CRUDServices.Project>();

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var rq = new ProjectQuery();
                    rq.Settings = new SearchSettings();
                    var rqResult = (ProjectResult)client.Query(rq);
                    if (rqResult != null)
                    {
                        foreach (CRUDServices.Project dto in rqResult.List)
                        {
                            if (dto != null)
                            {
                                projects.Add(dto);
                            }
                        }
                    }
                });

            return projects;
        }

        /// <summary>
        ///     The get regions.
        /// </summary>
        /// <returns>
        ///     The <see cref="List" />.
        /// </returns>
        public static List<Region> GetRegions()
        {
            var regions = new List<Region>();

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var rq = new RegionsQuery();
                    rq.Settings = new SearchSettings();
                    var rqResult = (RegionsResult)client.Query(rq);
                    if (rqResult != null)
                    {
                        foreach (CRUDServices.Region dto in rqResult.List)
                        {
                            if (dto != null)
                            {
                                regions.Add(Region.Convert(dto));
                            }
                        }
                    }
                });

            return regions;
        }

        /// <summary>
        ///     The get roles.
        /// </summary>
        /// <returns>
        ///     The <see cref="List" />.
        /// </returns>
        public static List<ProjectMeetingRole> GetRoles()
        {
            var profiles = new List<ProjectMeetingRole>();

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var rq = new ProjectMeetingRoleQuery();
                    rq.Settings = new SearchSettings();
                    var rqResult = (ProjectMeetingRoleResult)client.Query(rq);
                    if (rqResult != null)
                    {
                        foreach (ProjectMeetingRole dto in rqResult.List)
                        {
                            if (dto != null)
                            {
                                profiles.Add(dto);
                            }
                        }
                    }
                });

            return profiles;
        }

        // get a list of all clusterstatustypes

        /// <summary>
        ///     The get topics.
        /// </summary>
        /// <returns>
        ///     The <see cref="List" />.
        /// </returns>
        public static List<Topic> GetTopics()
        {
            return GetTopicsWithIDs(new List<Guid>());
        }

        /// <summary>
        /// The get topics with i ds.
        /// </summary>
        /// <param name="IDs">
        /// The i ds.
        /// </param>
        /// <returns>
        /// The <see cref="List"/>.
        /// </returns>
        public static List<Topic> GetTopicsWithIDs(IEnumerable<Guid> IDs)
        {
            var tops = new List<Topic>();
            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var query = new TopicQuery();
                    query.Settings = new SearchSettings
                    {
                        OrderBy = "Name",
                        Skip = 0,
                        Take = 10000,
                        SortAscending = true
                    };
                    if (IDs != null && IDs.Count() > 0)
                    {
                        query.Settings.IDIsIn = IDs.ToArray();
                    }

                    var res = client.Query(query) as TopicResult;

                    if (res != null)
                    {
                        foreach (Topic top in res.List)
                        {
                            tops.Add(top);
                        }
                    }
                });

            return tops;
        }

        /// <summary>
        /// The get users with i ds.
        /// </summary>
        /// <param name="IDs">
        /// The i ds.
        /// </param>
        /// <returns>
        /// The <see cref="List"/>.
        /// </returns>
        public static List<User> GetUsersWithIDs(IEnumerable<Guid> IDs)
        {
            var users = new List<User>();

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var rq = new UsersQuery();
                    rq.Settings = new SearchSettings();
                    rq.Settings.IDIsIn = IDs.ToArray();
                    var rqResult = (UsersResult)client.Query(rq);
                    if (rqResult != null)
                    {
                        foreach (User dto in rqResult.List)
                        {
                            if (dto != null)
                            {
                                users.Add(dto);
                            }
                        }
                    }
                });

            return users;
        }


        public static List<CRUDServices.File> GetFilesWithoutBytesOfCluster(Guid clusterID)
        {
            List<CRUDServices.File> files = new List<CRUDServices.File>();

            CRUDServiceProvider.WithCRUDService(client =>
                {
                    ClusterQuery query = new ClusterQuery()
                    {
                        Settings = new SearchSettings() { IDEquals = clusterID }
                    };
                    var clusterRes = client.Query(query) as ClusterResult;
                    if (clusterRes != null && clusterRes.List.Any())
                    {
                        var clusterMethodIds = clusterRes.List[0].Methods;

                        if (clusterMethodIds.Any())
                        {
                            List<CRUDServices.ClusterMethod> clusterMethods = GetClusterMethodsWithIDs(clusterMethodIds);

                            List<Guid> fileIDs = new List<Guid>();
                            foreach (var clusterMethod in clusterMethods)
                            {
                                fileIDs.AddRange(clusterMethod.Files);
                            }

                            if (fileIDs.Any())
                            {
                                files.AddRange(GetFilesWithoutBytesWithIDs(fileIDs));
                            }
                        }
                    }
                });

            return files;
        }


        public static List<CRUDServices.File> GetFilesWithoutBytesWithIDs(List<Guid> fileIds)
        {
            List<CRUDServices.File> files = new List<CRUDServices.File>();

            CRUDServiceProvider.WithCRUDService(client =>
            {

                if (fileIds.Any())
                {
                    FileQuery fileQuery = new FileQuery()
                    {
                        Settings = new SearchSettings() { IDIsIn = fileIds.ToArray() },
                        OnlyFileInfo = true
                    };

                    var filesRes = client.Query(fileQuery) as FileResult;
                    if (filesRes != null && filesRes.List.Any())
                    {
                        files.AddRange(filesRes.List);
                    }
                }
            });

            return files;
        }

        public static LogView GetLogViewForObject(Guid objectID, int? skip, int? take)
        {
            LogView view = new LogView()
            {
                List = new List<LogEntry>(),
                AllUsers = PrimitiveTypes.GetUsersWithIDs(new List<Guid>())
            };

            CRUDServiceProvider.WithCRUDService(client =>
            {
                var logQuery = new LogEntryQuery()
                {
                    EditedObjectID = objectID,
                    Settings = new SearchSettings()
                    {
                        Skip = skip,
                        Take = take
                    }
                };

                var logResult = client.Query(logQuery) as LogEntryResult;
                if (logResult != null)
                {
                    view.List = logResult.List.ToList();
                }
            });

            return view;
        }


        public static LogView GetLogViewForUser(Guid? userID, DateTime? from, DateTime? to) 
        {
            LogView view = new LogView()
            {
                List = new List<LogEntry>(),
                AllUsers = PrimitiveTypes.GetUsersWithIDs(new List<Guid>())
            };

            CRUDServiceProvider.WithCRUDService(client =>
            {
                var logQuery = new LogEntryQuery()
                {
                    Settings = new SearchSettings()
                };

                if (userID.HasValue && userID.Value != Guid.Empty)
                {
                    logQuery.EditorID = userID.Value;
                }

                if (from.HasValue)
                {
                    logQuery.Settings.CreationDateFrom = from.Value;
                }

                if (to.HasValue)
                {
                    logQuery.Settings.CreationDateTo = to.Value;
                }

                var logResult = client.Query(logQuery) as LogEntryResult;
                if (logResult != null)
                {
                    view.List = logResult.List.ToList();
                }
            });

            return view;
        }

        #endregion
    }
}